package data

import (
	"autotestservice/testservices/internal/types"
	"errors"
	"gitee.com/jmdvirus/jkgo/jk/jklog"
	"gitee.com/jmdvirus/jkgo/jk/utils"
	"gitee.com/jmdvirus/jkgo/jkdbs"
	"gopkg.in/mgo.v2/bson"
	"time"
)

var globalMongo *jkdbs.Mongo

type DBTestProjectItem struct {
	Id         string `json:"id"`
	TestId     string `json:"testId"`
	ProjectId  string `json:"projectId"`
	Name       string `json:"name"`
	Result     bool   `json:"result"`
	Content    string `json:"content"`
	PreResult  string `json:"preResult"`
	RealResult string `json:"realResult"`
	TimeStart  int64  `json:"timeStart"`
	TimeEnd    int64  `json:"timeEnd"`
}

const murl = "mongodb://localhost"

func init() {
	globalMongo = jkdbs.NewMongo(murl)
}

func AutoTestTestItemGet(model string) (*types.TestItemList, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return nil, errors.New("db not open")
		}
	}

	result := &types.TestItemList{}
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return result, errors.New("db not open")
		}
	}

	if len(model) == 0 {
		err := globalMongo.DB("proj").C("testoption").Find(nil).All(&result.Items)
		if err != nil {
			jklog.L().Errorln("no data")
			return result, err
		}
		return result, nil
	}
	find := utils.M{
		"model": model,
	}

	err := globalMongo.DB("proj").C("testoption").Find(find).All(&result.Items)
	if err != nil {
		jklog.L().Errorln("get fail, ", err)
		return result, err
	}
	return result, nil
}

func AutoTestOptionAdd(item types.TestOptionAdd) (*types.TestItem, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return nil, errors.New("db not open")
		}
	}

	err := globalMongo.DB("proj").C("testoption").Insert(item.Item)
	if err != nil {
		jklog.L().Errorln("insert fail ", err)
		return nil, err
	}
	return &item.Item, nil
}

func AutoTestOptionUpdate(item types.TestOptionUpdate) (*types.TestItem, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return nil, errors.New("db not open")
		}
	}

	find := utils.M{"id": item.Item.Id}

	origin := types.TestItem{}
	globalMongo.DB("proj").C("testoption").Find(find).One(&origin)

	err := globalMongo.DB("proj").C("testoption").Update(find, item.Item)
	if err != nil {
		jklog.L().Errorln("update fail", err)
		return &origin, err
	}
	return &item.Item, nil
}

func AutoTestOptionRemove(item types.TestOptionRemove) error {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return errors.New("db not open")
		}
	}

	find := utils.M{"id": item.Id}
	err := globalMongo.DB("proj").C("testoption").Remove(find)
	if err != nil {
		jklog.L().Errorln("remove fail ", err)
		return err
	}
	return nil
}

func AutoTestTestItemSet(list types.TestItemList) (types.TestItemList, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return list, errors.New("db not open")
		}
	}

	i := 0
	for _, v := range list.Items {
		err := globalMongo.DB("proj").C("testoption").Insert(v)
		if err != nil {
			jklog.L().Errorln("get fail, ", err)
			i = i + 1
		}
	}
	if i > 0 {
		jklog.L().Errorln("some insert fail ", i)
		return list, errors.New("some insert fail")
	}
	return list, nil
}

func AutoTestTestProjectStart(project types.TestProject) (types.TestProject, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return project, errors.New("db not open")
		}
	}

	project.TimeStart = time.Now().Unix()
	project.TimeEnd = 0

	err := globalMongo.DB("proj").C("testproject").Insert(project)
	if err != nil {
		jklog.L().Errorln("insert fail, ", err)
		return project, err
	}
	return project, nil
}

func AutoTestTestProjectStop(project types.TestProject) (types.TestProject, error) {
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return project, errors.New("db not open")
		}
	}

	project.TimeEnd = time.Now().Unix()
	find := bson.M{"id": project.Id}
	data := bson.M{"$set": bson.M{"timeend": project.TimeEnd}}

	err := globalMongo.DB("proj").C("testproject").Update(find, data)
	if err != nil {
		jklog.L().Errorln("update fail, ", err, " of id ", project.Id)
		return project, err
	}
	return project, nil
}

func AutoTestTestProjectItemSet(project DBTestProjectItem) (types.TestProjectItem, error) {
	tpi := types.TestProjectItem{}
	tpi.Id = project.Id
	tpi.Result = project.Result
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return tpi, errors.New("db not open")
		}
	}

	err := globalMongo.DB("proj").C("testprojectitem").Insert(project)
	if err != nil {
		jklog.L().Errorln("insert fail, ", err)
		return tpi, err
	}
	return tpi, nil
}

func AutoTestTestProjectItemManualUpdateResult(project DBTestProjectItem) (types.TestProjectItem, error) {
	tpi := types.TestProjectItem{}
	tpi.Id = project.Id
	tpi.Result = project.Result
	if globalMongo == nil {
		globalMongo = jkdbs.NewMongo(murl)
		if globalMongo == nil {
			return tpi, errors.New("db not open")
		}
	}

	now := time.Now().Unix()

	find := utils.M{"id": project.Id}
	data := utils.M{"$set": bson.M{"result": project.Result, "realresult": project.Content, "timeend": now}}
	tpi.TimeEnd = now

	err := globalMongo.DB("proj").C("testprojectitem").Update(find, data)
	if err != nil {
		jklog.L().Errorln("insert fail, ", err)
		return tpi, err
	}
	return tpi, nil
}
